package com.adnaan.backend.controller.wechat;

import cn.dev33.satoken.annotation.SaIgnore;
import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.json.JSONObject;
import com.adnaan.backend.common.annotation.RestControllerMapping;
import com.adnaan.backend.common.model.Result;
import com.adnaan.backend.entity.SysUser;
import com.adnaan.backend.service.SysUserService;
import com.adnaan.backend.utils.WechatLoginUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * author: adnaan
 * create: 2025-02-16 16:39
 * Description:
 */
@Slf4j
@RestControllerMapping("/wechat")
@Tag(name = "微信小程序登录", description = "微信小程序登录")
@ApiSupport(author = "adnaan", order = 7)
public class WxLoginController {

    @Resource
    private SysUserService userService;

    @Operation(summary = "微信小程序登录")
    @GetMapping("/login")
    @SaIgnore
    public Result<Map<String, String>> login(@RequestParam String code) {
        try {
            JSONObject loginObject = WechatLoginUtil.code2Session(code);
            String openid = loginObject.getStr("openid");
            if (openid == null) {
                return Result.error("获取 openid 失败");
            }

            SysUser user = userService.getOne(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getOpenId, openid));
            if (user == null) {
                log.info("用户不存在，openid: {}", openid);
                user = new SysUser();
                user.setOpenId(openid);
                user.setUsername(UsernameGenerator.generateRandomUsername());
                user.setPassword(encryptPassword(openid));
                user.setStatus(1);
                try {
                    userService.save(user);
                    //只有一个角色，转为List
                    List<String> roleIds = List.of("5");
                    userService.insertRoles(user.getId(), roleIds);
                    log.info("新用户创建成功，openid: {}", openid);
                } catch (Exception e) {
                    log.error("保存用户失败", e);
                    return Result.error("用户创建失败，请检查字段约束");
                }
            }
            if (user.getStatus() == 0) {
                return Result.error("该用户已被禁用");
            }
            StpUtil.login(user.getId(), "mini_program");
            SaTokenInfo tokenInfo = StpUtil.getTokenInfo();
            userService.setLastLoginTime(user.getId());
            log.info("用户登录成功，openid: {}", openid);
            log.info("token: {}", tokenInfo.getTokenValue());
            Map<String, String> map = new HashMap<>();
            map.put("tokenHead", tokenInfo.getTokenName());
            map.put("token", tokenInfo.getTokenValue());
            return Result.success(map);
        } catch (IOException e) {
            log.error("微信登录获取 openid 失败", e);
            return Result.error("微信登录失败");
        }
    }

    // 简单的密码加密示例，实际应用中应使用更安全的加密算法
    private String encryptPassword(String password) {
        // 这里可以使用 BCrypt 等加密算法，示例只是简单返回原密码
        return password;
    }

    // 用户名生成工具类
    static class UsernameGenerator {
        public static String generateRandomUsername() {
            return UUID.randomUUID().toString().replace("-", "").substring(0, 10);
        }
    }
}
